package com.zhuhjay.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhuhjay.common.properties.LoggingSystemProperties;
import com.zhuhjay.common.exception.CustomException;
import com.zhuhjay.common.utils.ClientUtils;
import com.zhuhjay.common.utils.FileLoadUtils;
import com.zhuhjay.common.utils.ServletUtils;
import com.zhuhjay.system.domain.entity.User;
import com.zhuhjay.system.domain.vo.RegisterUser;
import com.zhuhjay.system.domain.vo.UserInfo;
import com.zhuhjay.system.mapper.UserMapper;
import com.zhuhjay.system.service.IUserService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zhuhjay
 * @since 2022-03-20
 */
@Service
@Transactional(rollbackFor = CustomException.class)
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final LoggingSystemProperties properties;
    private final BCryptPasswordEncoder passwordEncoder;

    public UserServiceImpl(LoggingSystemProperties loggingSystemProperties,
                           BCryptPasswordEncoder passwordEncoder) {
        this.properties = loggingSystemProperties;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public void saveUser(RegisterUser registerUser) {
        // 先判断该用户账号是否被使用
        User userByUsername = getUserByUsername(registerUser.getUsername());
        if( userByUsername != null ){
            throw new CustomException("账号{" + registerUser.getUsername() + "}已被使用, 请换个重试");
        }
        User user = new User();
        user.setUsername(registerUser.getUsername());
        user.setUserNike(registerUser.getUserNike());
        user.setPassword(passwordEncoder.encode(registerUser.getPassword()));
        user.setSex(registerUser.getSex());
        user.setEmail(registerUser.getEmail());
        user.setTelephone(registerUser.getTelephone());
        user.setAddress(registerUser.getAddress());
        user.setCreateTime(new Date());
        int insert = baseMapper.insert(user);
        if( insert != 1 ){
            throw new CustomException("新用户创建失败");
        }
    }

    @Override
    public void setLoginInfo(Integer id) {
        // 登陆后 后台修改一些登录信息
        HttpServletRequest request = ServletUtils.getRequest();
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper
                .eq("id", id)
                .set("loginIp", ClientUtils.getIpAddress(request))
                .set("loginDate", new Date());
        baseMapper.update(null, updateWrapper);
    }

    @Override
    public User getUserByUsername(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        return baseMapper.selectOne(queryWrapper);
    }

    @Override
    public User getUserInfoById(Integer id) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("id", id)
                // 根据字段进行排除查询
                .select(User.class, field -> !"password".equals(field.getColumn()));
        return baseMapper.selectOne(queryWrapper);
    }

    @Override
    public String setUserAvatarById(Integer id, MultipartFile file) {
        checkDisable(id);
        String fileName = FileLoadUtils.fileUpload(file, properties.getAvatarPath(),
                                    new String[]{"png", "jpg", "jpeg", "ico", "gif"});
        // /profile/avatar/fileName
        String filePath = properties.getStaticPath() + properties.getAvatarDir() + "/" + fileName;
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper
                .eq("id", id)
                .set("avatar", filePath);
        int update = baseMapper.update(null, updateWrapper);
        if( update != 1 ){
            throw new CustomException("头像修改失败, 请重试");
        }
        return filePath;
    }

    @Override
    public void setUserInfoById(Integer id, UserInfo userInfo) {
        checkDisable(id);
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper
                .eq("id", id)
                .set("userNike", userInfo.getUserNike())
                .set("sex", userInfo.getSex())
                .set("telephone", userInfo.getTelephone())
                .set("email", userInfo.getEmail())
                .set("address", userInfo.getAddress());
        int update = baseMapper.update(null, updateWrapper);
        if( update != 1 ){
            throw new CustomException("信息修改失败");
        }
    }

    @Override
    public void setPassword(Integer id, String password) {
        checkDisable(id);
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper
                .eq("id", id)
                .set("password", passwordEncoder.encode(password));
        int update = baseMapper.update(null, updateWrapper);
        if( update != 1 ){
            throw new CustomException("密码修改失败");
        }
    }

    @Override
    public Page<User> getUserList(Integer id, Integer pageNum, Integer pageSize) {
        Page<User> userPage = new Page<>(pageNum, pageSize);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper
                // 查询除了当前操作的id外
                .ne("id", id)
                .orderByDesc("id")
                .select(User.class, field -> !"password".equals(field.getColumn()));
        return baseMapper.selectPage(userPage, queryWrapper);
    }

    /** 实现测试账号(id=1)的信息不能被修改 **/
    private void checkDisable(Integer id){
        if( id == 1 ){
            throw new CustomException("测试账号禁用修改信息接口, 可以切换账号尝试");
        }
    }

}
